package com.suning.sawp.service.impl.bi.support;

import java.io.File;
import java.io.IOException;
import java.io.Writer;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Charsets;
import com.google.common.io.Files;
import com.suning.istore.common.integration.ErrorLineHandler;
import com.suning.istore.common.integration.ftp.FileProcessorContext;
import com.suning.istore.common.integration.ftp.LineBasedFileProcessorContext;

/**
 * 文件处理上下文，用作单例
 * 
 * @author 13071602
 *
 */
public abstract class ReportableBIFileContext extends LineBasedFileProcessorContext
        implements FileProcessorContext, ErrorLineHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(ReportableBIFileContext.class);

    protected static final int DEFAULT_BATCH_SIZE = 500;

    private class ErrorFile {
        private File currentFile;
        private Writer currentWriter;
        private int currentErrCounts = 0;

        public ErrorFile(String prefix) throws IOException {
            open(prefix);
        }

        private void open(String prefix) throws IOException {
            currentFile = File.createTempFile(prefix + ".", ".error");
            currentWriter = Files.newWriter(currentFile, Charsets.UTF_8);
        }

        public void log(String line) {
            currentErrCounts++;
            try {
                currentWriter.append(line).append(getLineDelimiter());
            } catch (IOException ex) {
                throw new IllegalStateException(ex);
            }
        }

        @Override
        public String toString() {
            return String.format("错误日志:%s,错误数:%d", currentFile.getAbsolutePath(), currentErrCounts);
        }

        public boolean hasError() {
            return currentErrCounts > 0;
        }

        /**
         * 
         * @return 是否有错误日志
         */
        public void close() {
            IOUtils.closeQuietly(currentWriter);
            if (currentErrCounts == 0) {
                currentFile.delete();
            }
        }
    }

    private int totalErrCounts = 0;
    private ErrorFile errorFile = null;

    @Override
    public void handlerErrorLine(String line, Exception e) {
        totalErrCounts++;
        errorFile.log(line);
        LOGGER.error(line, e);
    }

    @Override
    public void beforeFile(String fileName) {
        try {
            errorFile = new ErrorFile(fileName);
        } catch (IOException e) {
            throw new IllegalStateException("环境检查失败,无法打开文件", e);
        }
    }

    public void completeBatch(String batchName, int total) {
        String msg = String.format("任务[%s]失败%d/%d条", batchName, totalErrCounts, total);
        LOGGER.info(msg);
        if (totalErrCounts > 0) {
            throw new IllegalStateException(msg);
        }
    };

    @Override
    public void endFile(String fileName, int total) {
        LOGGER.info(String.format("处理文件%s,%s条", fileName, total));
        errorFile.close();
        if (errorFile.hasError()) {
            LOGGER.error("存在异常:{}", errorFile);
        }
    }
}